.TH std::generator 3 "2024.06.10" "http://cppreference.com" "C++ Standard Libary"
.SH NAME
std::generator \- std::generator

.SH Synopsis
   Defined in header <generator>
   template<

       class Ref,
       class V = void,                                                \fB(1)\fP (since C++23)
       class Allocator = void >
   class generator

       : public ranges::view_interface<generator<Ref, V, Allocator>>
   namespace pmr {

       template< class Ref, class V = void >
       using generator =                                              \fB(2)\fP (since C++23)
           std::generator<Ref, V, std::pmr::polymorphic_allocator<>>;

   }

   1) The class template std::generator presents a view of the elements yielded by the
   evaluation of a coroutine.
   2) Convenience alias template for the generator using the polymorphic allocator.

   A std::generator generates a sequence of elements by repeatedly resuming the
   coroutine from which it was returned. Each time a co_yield statement is evaluated,
   the coroutine produces one element of the sequence. When the co_yield statement is
   of the form co_yield ranges::elements_of(rng), each element of the range rng is
   successively produced as an element of the sequence.

   std::generator models view and input_range.

   The behavior of a program that adds a specialization for std::generator is
   undefined.

.SH Template parameters

   Ref       - the reference type (ranges::range_reference_t) of the generator. If V is
               void, both the reference type and the value type are inferred from Ref
   V         - the value type (range_value_t) of the generator, or void
   Allocator - an allocator type or void

   If Allocator is not void, then the behavior is undefined if Allocator does not meet
   the Allocator requirements.

.SH Member types

   Member type      Definition
                    std::conditional_t<std::is_void_v<V>, std::remove_cvref_t<Ref>,
   value (private)  V>;.
                    (exposition-only member type*)
   reference        std::conditional_t<std::is_void_v<V>, Ref&&, Ref>;.
   (private)        (exposition-only member type*)
   yielded          std::conditional_t<std::is_reference_v<reference>, reference, const
                    reference&>.

.SH Type requirements
   -
   std::allocator_traits<Allocator>::pointer is a pointer type.
   -
   value is a cv-unqualified object type.
   -
   reference is either a reference type, or a cv-unqualified object type that models
   copy_constructible.
   -
   Let /*RRef*/ denote:std::remove_reference_t</*reference*/>&&, if /*reference*/ is a
   reference type, and /*reference*/ otherwise.
     * std::common_reference_with</*reference*/&&, /*value*/&> is modeled.
     * std::common_reference_with</*reference*/&&, /*RRef*/&&> is modeled.
     * std::common_reference_with</*RRef*/&&, const /*value*/&> is modeled.

   The program is ill-formed if any of these type requirements is not satisfied.

.SH Member objects

   Member name  Definition
                Internally, each active instance of std::generator is associated with a
                stack (handled as if by object of type
                std::unique_ptr<std::stack<std::coroutine_handle<>>>).

                  * When begin is called, a new stack is created and the generator is
                    added to the stack.
   active_        * When co_yield ranges::elements_of(rng) is evaluated in a generator
   (private)        body, rng is converted to a generator and added to the stack that
                    contains the enclosing generator.
                  * When a generator iterator is incremented, the coroutine at the top
                    of the associated stack is resumed.
                  * When a generator finishes (i.e. when final_suspend is called), it
                    is removed from the stack.
                    (exposition-only member object*)
   coroutine_   a handle of type std::coroutine_handle<promise_type>
   (private)    (exposition-only member object*)

.SH Member functions

   constructor   constructs a generator object
                 \fI(public member function)\fP
   destructor    effectively destroys the entire stack of yielded generators
                 \fI(public member function)\fP
   operator=     assigns a generator object
                 \fI(public member function)\fP
                 resumes the initially suspended coroutine and returns an iterator to
   begin         its handle
                 \fI(public member function)\fP
   end           returns std::default_sentinel
                 \fI(public member function)\fP
         Inherited from std::ranges::view_interface
   empty         returns whether the derived view is empty. Provided if it satisfies
   (C++20)       sized_range or forward_range.
                 \fI(public member function of std::ranges::view_interface<D>)\fP
   cbegin        returns a constant iterator to the beginning of the range.
   (C++23)       \fI(public member function of std::ranges::view_interface<D>)\fP
   cend          returns a sentinel for the constant iterator of the range.
   (C++23)       \fI(public member function of std::ranges::view_interface<D>)\fP
   operator bool returns whether the derived view is not empty. Provided if
   (C++20)       ranges::empty is applicable to it.
                 \fI(public member function of std::ranges::view_interface<D>)\fP

   Nested classes

   promise_type the promise type
                \fI(public member class)\fP
   iterator     the iterator type
                (exposition-only member class*)

.SH Notes

   Feature-test macro   Value    Std                       Feature
   __cpp_lib_generator 202207L (C++23) std::generator – synchronous coroutine generator
                                       for ranges

.SH Example

   Can be tried in Compiler Explorer


// Run this code

 #include <generator>
 #include <iostream>

 template<typename T>
 struct Tree
 {
     T value;
     Tree *left{}, *right{};

     std::generator<const T&> traverse_inorder() const
     {
         if (left)
             for (const T& x : left->traverse_inorder())
                 co_yield x;

         co_yield value;
         if (right)
             for (const T& x : right->traverse_inorder())
                 co_yield x;
     }
 };

 int main()
 {
     Tree<char> tree[]
     {
                                     {'D', tree + 1, tree + 2},
         //                            │
         //            ┌───────────────┴────────────────┐
         //            │                                │
                     {'B', tree + 3, tree + 4},       {'F', tree + 5, tree + 6},
         //            │                                │
         //  ┌─────────┴─────────────┐      ┌───────────┴─────────────┐
         //  │                       │      │                         │
           {'A'},                  {'C'}, {'E'},                    {'G'}
     };

     for (char x : tree->traverse_inorder())
         std::cout << x << ' ';
     std::cout << '\\n';
 }

.SH Output:

 A B C D E F G

.SH References

     * C++23 standard (ISO/IEC 14882:2023):

     * 26.8 Range generators [coro.generator]

.SH See also

   noop_coroutine creates a coroutine handle that has no observable effects when
   (C++20)        resumed or destroyed
                  \fI(function)\fP
